using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
using Contrib.AppFabric.Models;
using Microsoft.ApplicationServer.Caching;
using Microsoft.ApplicationServer.Caching.AdminApi;
using Microsoft.ApplicationServer.Caching.Commands;
using Orchard;

namespace Contrib.AppFabric.Services {
    public interface IAppFabricPowerShellService : IDependency {
        string GetCacheStatistics(PowerShellSettings powerShellSettings);
        void GetCacheClusterHealth(PowerShellSettings powerShellSettings);
        void GetCacheHost(PowerShellSettings powerShellSettings);
    }

    public class AppFabricPowerShellService : IAppFabricPowerShellService {
        private Collection<PSObject> RunCommand(PowerShellSettings powerShellSettings, Action<PowerShell> commandMethod) {
            //// http://www.bandgap.cs.rice.edu/classes/comp410/resources/Using%20Windows%20Workflow%20Foundation/AppFabric%20Management.aspx
            //var securePassword = new SecureString();
            //foreach (var item in powerShellSettings.RemoteCredentials.Password.ToCharArray())
            //    securePassword.AppendChar(item);

            //PSCredential psc = new PSCredential(powerShellSettings.RemoteCredentials.Username, securePassword);

            //// TCP port is SSL port for WinRM. Make sure it is open thru firewall!
            //WSManConnectionInfo rri = new WSManConnectionInfo(
            //    powerShellSettings.RemoteCredentials.UseSSL,
            //    powerShellSettings.RemoteCredentials.ComputerName,
            //    powerShellSettings.RemoteCredentials.Port,
            //    "wsman",
            //    "",
            //    psc);
            
            //rri.AuthenticationMechanism = AuthenticationMechanism.Negotiate;

            //Runspace remoteRunspace = RunspaceFactory.CreateRunspace(rri);
            //remoteRunspace.Open();

            using (PowerShell powershell = PowerShell.Create()) {
                //powershell.Runspace = remoteRunspace;

                //powershell.AddScript("Import-Module ApplicationServer\\Microsoft.ApplicationServer.Management.dll \nget-asappservice");

                powershell.AddCommand("Import-Module");
                powershell.AddParameter("Name", "DistributedCacheAdministration");
                powershell.Invoke();

                Command cmd = new Command("Use-CacheCluster");
                cmd.Parameters.Add(new CommandParameter("Provider", powerShellSettings.CacheHost.Provider));
                cmd.Parameters.Add(new CommandParameter("ConnectionString", powerShellSettings.CacheHost.ConnectionString));
                powershell.Commands.AddCommand(cmd);

                commandMethod(powershell);

                var invokeResults = powershell.Invoke();

                //remoteRunspace.Close();

                return invokeResults;
            }
        }

        public string GetCacheStatistics(PowerShellSettings powerShellSettings) {
            Collection<PSObject> returnValues = RunCommand(powerShellSettings, shell => {
                Command command = new Command("Get-CacheStatistics");
                command.Parameters.Add(new CommandParameter("CachePort", powerShellSettings.CacheHost.CachePort));
                command.Parameters.Add(new CommandParameter("HostName", powerShellSettings.CacheHost.CacheHost));
                
                shell.Commands.AddCommand(command);
            });

            foreach (var returnValue in returnValues) {
                var stats = ((HostCacheStats) returnValue.BaseObject);

                
            }
            
            
            return null;
        }

        public void GetCacheClusterHealth(PowerShellSettings powerShellSettings) {
            Collection<PSObject> returnValues = RunCommand(powerShellSettings, shell => {
                Command command = new Command("Get-CacheClusterHealth");
                shell.Commands.AddCommand(command);
            });
            
            foreach (var returnValue in returnValues) {
                var stats = ((ClusterHealth)returnValue.BaseObject);
                foreach (var host in stats.Hosts) {
                    foreach (var namedCache in host.NamedCaches) {
                        var health = namedCache[NamedCacheHealthPerHost.Healthy];
                        var inadequateSecondaries = namedCache[NamedCacheHealthPerHost.InadequateSecondaries];
                        var notPrimary = namedCache[NamedCacheHealthPerHost.NotPrimary];
                        var throttled = namedCache[NamedCacheHealthPerHost.Throttled];
                        var underReconfiguration = namedCache[NamedCacheHealthPerHost.UnderReconfiguration];
                    }
                }
            }
        }

        public void GetCacheHost(PowerShellSettings powerShellSettings) {
            Collection<PSObject> returnValues = RunCommand(powerShellSettings, shell => {
                Command command = new Command("Get-CacheHost");
                command.Parameters.Add(new CommandParameter("CachePort", powerShellSettings.CacheHost.CachePort));
                command.Parameters.Add(new CommandParameter("HostName", powerShellSettings.CacheHost.CacheHost));
                shell.Commands.AddCommand(command);
            });

            foreach (var returnValue in returnValues) {
                var hostInfo = ((HostInfo) returnValue.BaseObject);
                
            }
        }
    }

    //public class PowerShellCacheCredentialsSettings {
    //    public string Username { get; set; }
    //    public string Password { get; set; }

    //    public bool IsLocal { get; set; }
    //    public bool UseSSL { get; set; }
    //    public string ComputerName { get; set; }
    //    public int Port { get; set; }
    //}
}